Motivation
Reviewer Comments addressed here:
Toward this end, the EOD waveform can be characterized by dozens of
additional parameters beyond just the overall waveform duration. This is
important in the present case because these parameters might provide
clues about the underlying passive and ionic mechanisms that change EOD
waveform at the level of the electrocyte, for example:
- the durations of P1 and P2 ✅,
- the rise slope of P1 ✅,
- the decay characteristics of P2 (single vs. multiple time constant)
✅
nb: The single time constant seemed to fit adequately, not sure a
multiple time constant is needed,
- changes in the delay between the peaks of P1 and P2 ✅,
- changes in the relative amplitude of P1 and P2, etc ✅.
- Parameters such as these should at least be reported for the sake of
completeness ✅.
eod_measurement_path<-file.path(root, "output_data/norm_measurement_data.csv")
eod_measurement_data<-read.table(eod_measurement_path,header=T,sep = ",")
eod_measurement_data$duration<-eod_measurement_data$tT2-eod_measurement_data$tT1
eod_measurement_data$p1_duration<-eod_measurement_data$tZC2-eod_measurement_data$tP1
eod_measurement_data$p2_duration<-eod_measurement_data$tP2-eod_measurement_data$tZC2
eod_measurement_data$vP2.vP1.ratio<-eod_measurement_data$vP2/eod_measurement_data$vP1
# Convert treatdate to proper Date format
eod_measurement_data <- filter(eod_measurement_data, period=="EXPT")
eod_measurement_data <- eod_measurement_data %>%
mutate(treatdate = as.Date(treatdate, format = "%d-%b"))
# Calculate n_days
eod_measurement_data <- eod_measurement_data %>%
group_by(individual) %>%
mutate(n_days = as.numeric(treatdate - min(treatdate))) %>%
mutate(treat_day = case_when(
(treatement %in% c("T8", "CON") & n_days == 8) ~ "last",
(treatement %in% c("T8", "CON") & n_days == 0) ~ "first",
(treatement == "T1" & n_days == 1) ~ "last",
(treatement == "T1" & n_days == 0) ~ "first",
TRUE ~ NA_character_ # All other rows are NA
)) %>%
ungroup()
# View the result
print(eod_measurement_data)
filt_eod_measurement_data <- eod_measurement_data %>%
filter(!is.na(treat_day))
filt_eod_measurement_data$treat_day<-as.factor(filt_eod_measurement_data$treat_day)
Duration
Let’s check overall duration first. This has been updated to
calculate duration the way that Mau does, so the results should be
identical.
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "duration",
y_axis_label = "EOD duration (msec)"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
P1 Duration and P2 Duration
P1 duration does increase in T8 day, but not by a huge margin. P2
duration, however increases pretty substantially. Interesting…
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "p1_duration",
y_axis_label = "P1 duration (msec)"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "p2_duration",
y_axis_label = "P2 duration (msec)"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
NA
Ratio of vP2 to vP1
A larger negative value means that P2 is “bigger” than P1. We can see
that VP2 is always larger on the first day, but becomes more
proportional after 8 days of T treatment. Does this suggest less Na+
expression?
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "vP2.vP1.ratio",
y_axis_label = "vP2/vP1 ratio"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "vP2",
y_axis_label = "vP2"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "vP1",
y_axis_label = "vP1"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
P1-P2 Delay
Since P1 is defined as T=0, then tP2 is the relative timing of P2. We
can see that it takes longer to reach P2 after 8 days of T treatment,
suggesting the action potentials are delayed relative to each other
(capacitance?)
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "tP2",
y_axis_label = "P1-P2 Delay (msec)"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
P2 Decay Time Constant
A larger τ indicates that the decay happens more rapidly. This means
P2’s amplitude diminishes over a larger time after testasterone
treatment. This suggests increased potassium channel expression, I
think.
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "decay_tau",
y_axis_label = "τ"
)
# Display the plot
print(results$plot)

results$anova
results$posthoc
Slope of P1
There is no significant difference here.
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "sS1",
y_axis_label = "Slope of P1"
)
No significant differences found between groups.
# Display the plot
print(results$plot)

results$anova
results$posthoc
NA
P0
P0 does in fact get larger with testasterone treatment as well,
though interestingly, the peak voltage stays the same, suggesting that
this change is because the peak is broader (lasts longer). Not sure what
would affect this, other than the electrocyte getting thicker? We don’t
know much about the ion channels present on the stalks, so this is an
interesting point to consider in a future study.
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "aP0",
y_axis_label = "Area P0"
)
No significant differences found between groups.
# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
data = filt_eod_measurement_data,
y_variable = "vP0",
y_axis_label = "Voltage of P0"
)
No significant differences found between groups.
# Display the plot
print(results$plot)

results$anova
results$posthoc
NA
Summary Table of All Comparisions
This code generates a summary table and outputs to word for editing
and inclusion in the manuscript.
statistics <- c("duration", "p1_duration", "p2_duration", "vP2.vP1.ratio", "tP2", "decay_tau","aP0","vP0","sS1","vP1","vP2")
# Filter, summarize, and format
summary_table <- filt_eod_measurement_data %>%
group_by(treat_day, treatement) %>% # Group by n_days and treatment
summarise(across(all_of(statistics),
~ sprintf("%.2f ± %.2f",
mean(.x, na.rm = TRUE),
sd(.x, na.rm = TRUE)),
.names = "{col}")) %>% # Combine mean and sd into a single column
ungroup() # Remove grouping
`summarise()` has grouped output by 'treat_day'. You can override using the `.groups` argument.
colnames(summary_table)<-c("Treatment Day","Treatment","Duration","P1 Duration","P2 Duration","vP2/vP1","tP2","τ","aP0","vP0","sS1","vP1","vP2")
# Create the flextable
flextable_table <- flextable(summary_table) %>%
bg(part = "header", bg = "#D3D3D3") %>% # Set header background color
bold(part = "header") %>% # Bold the header row
fontsize(size = 10, part = "all") %>% # Set font size for the entire table
autofit() %>% # Adjust column widths
set_table_properties(layout = "autofit") %>% # Fit table to layout
line_spacing(i = NULL, space = 1.2) # Add line spacing for better readability
# Define landscape section properties
landscape_section <- block_section(
prop_section(
page_size = page_size(orient = "landscape") # Set the page orientation to landscape
)
)
# Create the Word document
doc <- read_docx() %>%
body_add_flextable(flextable_table) %>% # Add the flextable
body_add(landscape_section) # Apply landscape section properties
# Export the Word document
print(doc, target = file.path(root,"output_data/eod_summary_norm.docx"))
flextable_table
Treatment Day | Treatment | Duration | P1 Duration | P2 Duration | vP2/vP1 | tP2 | τ | aP0 | vP0 | sS1 | vP1 | vP2 |
|---|
first | CON | 0.68 ± 0.13 | 0.03 ± 0.00 | 0.04 ± 0.00 | -1.44 ± 0.20 | 0.07 ± 0.01 | 31.06 ± 4.70 | -2.77 ± 0.83 | -0.02 ± 0.01 | 291.38 ± 71.18 | 0.41 ± 0.03 | -0.59 ± 0.03 |
first | T1 | 0.78 ± 0.07 | 0.04 ± 0.00 | 0.04 ± 0.01 | -1.46 ± 0.20 | 0.08 ± 0.01 | 26.88 ± 5.54 | -3.22 ± 1.31 | -0.03 ± 0.01 | 242.45 ± 47.25 | 0.41 ± 0.03 | -0.59 ± 0.03 |
first | T8 | 0.69 ± 0.09 | 0.03 ± 0.00 | 0.04 ± 0.00 | -1.54 ± 0.21 | 0.07 ± 0.01 | 32.04 ± 4.08 | -2.37 ± 0.50 | -0.02 ± 0.00 | 278.16 ± 64.73 | 0.40 ± 0.03 | -0.60 ± 0.03 |
last | CON | 0.68 ± 0.14 | 0.04 ± 0.01 | 0.04 ± 0.00 | -1.44 ± 0.21 | 0.07 ± 0.01 | 30.24 ± 5.40 | -2.65 ± 0.79 | -0.02 ± 0.01 | 293.72 ± 77.33 | 0.41 ± 0.03 | -0.59 ± 0.03 |
last | T1 | 0.83 ± 0.09 | 0.04 ± 0.01 | 0.04 ± 0.01 | -1.46 ± 0.18 | 0.08 ± 0.01 | 25.82 ± 5.12 | -3.25 ± 1.31 | -0.03 ± 0.01 | 237.71 ± 45.81 | 0.41 ± 0.03 | -0.59 ± 0.03 |
last | T8 | 1.35 ± 0.20 | 0.07 ± 0.01 | 0.09 ± 0.03 | -1.08 ± 0.28 | 0.16 ± 0.04 | 11.18 ± 3.07 | -3.98 ± 1.08 | -0.02 ± 0.01 | 227.10 ± 57.83 | 0.49 ± 0.08 | -0.51 ± 0.08 |
library(multcompView)
library(tidyr)
library(dplyr)
# Define the list of variables for which you want to add significance letters.
statistics <- c("duration", "p1_duration", "p2_duration", "vP2.vP1.ratio",
"tP2", "decay_tau", "aP0", "vP0", "sS1", "vP1", "vP2")
get_letters_by_day <- function(df, group_info, var) {
# Run Tukey's test for the given variable
tukey_res <- tukey_hsd(df, as.formula(paste(var, "~ treatement")))
# Create a matrix of p-values between treatment groups
groups <- sort(unique(df$treatement))
pmat <- matrix(1, nrow = length(groups), ncol = length(groups),
dimnames = list(groups, groups))
if(nrow(tukey_res) > 0) {
for(i in seq_len(nrow(tukey_res))) {
grp1 <- tukey_res$group1[i]
grp2 <- tukey_res$group2[i]
p_val <- tukey_res$p.adj[i]
pmat[grp1, grp2] <- p_val
pmat[grp2, grp1] <- p_val
}
}
# Compute grouping letters
letters_out <- multcompLetters(pmat, threshold = 0.05)$Letters
# Return only the treatment and letter columns.
# The grouping variable (treat_day) is added automatically.
data.frame(treatement = names(letters_out),
letter = letters_out,
stringsAsFactors = FALSE)
}
letters_list <- lapply(statistics, function(var) {
filt_eod_measurement_data %>%
group_by(treat_day) %>%
group_modify(~ get_letters_by_day(.x, .y, var)) %>%
ungroup() %>%
mutate(variable = var)
})
all_letters <- bind_rows(letters_list)
# Now, create your summary table as before.
# (We assume the summary_table was computed as in your previous chunk.)
summary_table <- filt_eod_measurement_data %>%
group_by(treat_day, treatement) %>% # Group by day and treatment
summarise(across(all_of(statistics),
~ sprintf("%.2f ± %.2f",
mean(.x, na.rm = TRUE),
sd(.x, na.rm = TRUE))),
.groups = "drop") # Combine mean and sd into a single column
# For nicer column names, rename (you can adjust this mapping as needed).
colnames(summary_table) <- c("Treatment Day","Treatment",
"Duration","P1 Duration","P2 Duration",
"vP2/vP1","tP2","τ","aP0","vP0","sS1","vP1","vP2")
# Since our letters are keyed by the original variable names (e.g., "duration")
# we set up a mapping to match the summary_table columns.
mapping_df <- tibble(
Variable = c("Duration", "P1 Duration", "P2 Duration", "vP2/vP1",
"tP2", "τ", "aP0", "vP0", "sS1", "vP1", "vP2"),
var = statistics
)
# Reshape the summary_table to long format to merge the letters.
summary_long <- summary_table %>%
pivot_longer(cols = -c(`Treatment Day`, Treatment),
names_to = "Variable",
values_to = "Summary") %>%
left_join(mapping_df, by = "Variable")
# Merge with the letters (join by treat_day/Treatment and the variable key).
# Note: In summary_table, "Treatment Day" corresponds to "treat_day" in all_letters.
summary_long <- summary_long %>%
left_join(all_letters, by = c("var" = "variable",
"Treatment Day" = "treat_day",
"Treatment" = "treatement"))
# Append the significance letter (if available) to the summary string.
summary_long <- summary_long %>%
mutate(Summary = ifelse(is.na(letter),
Summary,
paste0(Summary, " (", letter, ")")))
# (Optional) Pivot back to wide format.
summary_wide <- summary_long %>%
select(-var, -letter) %>%
pivot_wider(names_from = Variable, values_from = Summary)
# Create a flextable from the updated summary_wide table.
flextable_table_sig <- flextable(summary_wide) %>%
bg(part = "header", bg = "#D3D3D3") %>% # Header background color
bold(part = "header") %>% # Bold header row
fontsize(size = 10, part = "all") %>% # Font size for entire table
autofit() %>% # Adjust column widths
set_table_properties(layout = "autofit") %>% # Fit table to layout
line_spacing(i = NULL, space = 1.2) # Better readability
# Define landscape section properties for Word export
landscape_section <- block_section(
prop_section(
page_size = page_size(orient = "landscape") # Landscape orientation
)
)
# Create the Word document with the updated flextable.
doc <- read_docx() %>%
body_add_flextable(flextable_table_sig) %>% # Add flextable
body_add(landscape_section) # Apply landscape layout
# Export the Word document.
print(doc, target = file.path(root,"output_data/eod_summary_norm_with_sig.docx"))
# Display the updated flextable in the R Markdown output.
flextable_table_sig
Treatment Day | Treatment | Duration | P1 Duration | P2 Duration | vP2/vP1 | tP2 | τ | aP0 | vP0 | sS1 | vP1 | vP2 |
|---|
first | CON | 0.68 ± 0.13 (a) | 0.03 ± 0.00 (ab) | 0.04 ± 0.00 (a) | -1.44 ± 0.20 (a) | 0.07 ± 0.01 (ab) | 31.06 ± 4.70 (a) | -2.77 ± 0.83 (a) | -0.02 ± 0.01 (a) | 291.38 ± 71.18 (a) | 0.41 ± 0.03 (a) | -0.59 ± 0.03 (a) |
first | T1 | 0.78 ± 0.07 (a) | 0.04 ± 0.00 (a) | 0.04 ± 0.01 (a) | -1.46 ± 0.20 (a) | 0.08 ± 0.01 (a) | 26.88 ± 5.54 (a) | -3.22 ± 1.31 (a) | -0.03 ± 0.01 (a) | 242.45 ± 47.25 (a) | 0.41 ± 0.03 (a) | -0.59 ± 0.03 (a) |
first | T8 | 0.69 ± 0.09 (a) | 0.03 ± 0.00 (b) | 0.04 ± 0.00 (a) | -1.54 ± 0.21 (a) | 0.07 ± 0.01 (b) | 32.04 ± 4.08 (a) | -2.37 ± 0.50 (a) | -0.02 ± 0.00 (a) | 278.16 ± 64.73 (a) | 0.40 ± 0.03 (a) | -0.60 ± 0.03 (a) |
last | CON | 0.68 ± 0.14 (a) | 0.04 ± 0.01 (a) | 0.04 ± 0.00 (a) | -1.44 ± 0.21 (a) | 0.07 ± 0.01 (a) | 30.24 ± 5.40 (a) | -2.65 ± 0.79 (a) | -0.02 ± 0.01 (a) | 293.72 ± 77.33 (a) | 0.41 ± 0.03 (a) | -0.59 ± 0.03 (a) |
last | T1 | 0.83 ± 0.09 (a) | 0.04 ± 0.01 (a) | 0.04 ± 0.01 (a) | -1.46 ± 0.18 (a) | 0.08 ± 0.01 (a) | 25.82 ± 5.12 (a) | -3.25 ± 1.31 (a) | -0.03 ± 0.01 (a) | 237.71 ± 45.81 (a) | 0.41 ± 0.03 (a) | -0.59 ± 0.03 (a) |
last | T8 | 1.35 ± 0.20 (b) | 0.07 ± 0.01 (b) | 0.09 ± 0.03 (b) | -1.08 ± 0.28 (b) | 0.16 ± 0.04 (b) | 11.18 ± 3.07 (b) | -3.98 ± 1.08 (a) | -0.02 ± 0.01 (a) | 227.10 ± 57.83 (a) | 0.49 ± 0.08 (b) | -0.51 ± 0.08 (b) |
LS0tCnRpdGxlOiAiRGVlcCBEaXZlIG9uIEVPRCBDaGFuZ2VzIHdpdGggVGVzdGFzdGVyb25lIFRyZWF0bWVudCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgTW90aXZhdGlvbgoKUmV2aWV3ZXIgQ29tbWVudHMgYWRkcmVzc2VkIGhlcmU6CgpUb3dhcmQgdGhpcyBlbmQsIHRoZSBFT0Qgd2F2ZWZvcm0gY2FuIGJlIGNoYXJhY3Rlcml6ZWQgYnkgZG96ZW5zIG9mIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBiZXlvbmQganVzdCB0aGUgb3ZlcmFsbCB3YXZlZm9ybSBkdXJhdGlvbi4gVGhpcyBpcyBpbXBvcnRhbnQgaW4gdGhlIHByZXNlbnQgY2FzZSBiZWNhdXNlIHRoZXNlIHBhcmFtZXRlcnMgbWlnaHQgcHJvdmlkZSBjbHVlcyBhYm91dCB0aGUgdW5kZXJseWluZyBwYXNzaXZlIGFuZCBpb25pYyBtZWNoYW5pc21zIHRoYXQgY2hhbmdlIEVPRCB3YXZlZm9ybSBhdCB0aGUgbGV2ZWwgb2YgdGhlIGVsZWN0cm9jeXRlLCBmb3IgZXhhbXBsZToKCjEuIHRoZSBkdXJhdGlvbnMgb2YgUDEgYW5kIFAyIOKchSwgCjIuIHRoZSByaXNlIHNsb3BlIG9mIFAxIOKchSwgCjMuIHRoZSBkZWNheSBjaGFyYWN0ZXJpc3RpY3Mgb2YgUDIgKHNpbmdsZSB2cy4gbXVsdGlwbGUgdGltZSBjb25zdGFudCkg4pyFICAKICAgIG5iOiBUaGUgc2luZ2xlIHRpbWUgY29uc3RhbnQgc2VlbWVkIHRvIGZpdCBhZGVxdWF0ZWx5LCBub3Qgc3VyZSBhIG11bHRpcGxlIHRpbWUgY29uc3RhbnQgaXMgbmVlZGVkLCAKNC4gY2hhbmdlcyBpbiB0aGUgZGVsYXkgYmV0d2VlbiB0aGUgcGVha3Mgb2YgUDEgYW5kIFAyIOKchSwgCjUuIGNoYW5nZXMgaW4gdGhlIHJlbGF0aXZlIGFtcGxpdHVkZSBvZiBQMSBhbmQgUDIsIGV0YyDinIUuIAo2LiBQYXJhbWV0ZXJzIHN1Y2ggYXMgdGhlc2Ugc2hvdWxkIGF0IGxlYXN0IGJlIHJlcG9ydGVkIGZvciB0aGUgc2FrZSBvZiBjb21wbGV0ZW5lc3Mg4pyFLgoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpyb290PC1ycHJvanJvb3Q6OmZpbmRfcm9vdCgiLmdpdC9pbmRleCIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gcm9vdCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShtdWx0Y29tcFZpZXcpCmxpYnJhcnkoZmxleHRhYmxlKQpsaWJyYXJ5KG9mZmljZXIpCnNvdXJjZSgic3RhdHNfYW5kX3Bsb3QuUiIpCmBgYAoKYGBge3J9CmVvZF9tZWFzdXJlbWVudF9wYXRoPC1maWxlLnBhdGgocm9vdCwgIm91dHB1dF9kYXRhL25vcm1fbWVhc3VyZW1lbnRfZGF0YS5jc3YiKQplb2RfbWVhc3VyZW1lbnRfZGF0YTwtcmVhZC50YWJsZShlb2RfbWVhc3VyZW1lbnRfcGF0aCxoZWFkZXI9VCxzZXAgPSAiLCIpCmBgYAoKYGBge3J9CmVvZF9tZWFzdXJlbWVudF9kYXRhJGR1cmF0aW9uPC1lb2RfbWVhc3VyZW1lbnRfZGF0YSR0VDItZW9kX21lYXN1cmVtZW50X2RhdGEkdFQxCmVvZF9tZWFzdXJlbWVudF9kYXRhJHAxX2R1cmF0aW9uPC1lb2RfbWVhc3VyZW1lbnRfZGF0YSR0WkMyLWVvZF9tZWFzdXJlbWVudF9kYXRhJHRQMQplb2RfbWVhc3VyZW1lbnRfZGF0YSRwMl9kdXJhdGlvbjwtZW9kX21lYXN1cmVtZW50X2RhdGEkdFAyLWVvZF9tZWFzdXJlbWVudF9kYXRhJHRaQzIKZW9kX21lYXN1cmVtZW50X2RhdGEkdlAyLnZQMS5yYXRpbzwtZW9kX21lYXN1cmVtZW50X2RhdGEkdlAyL2VvZF9tZWFzdXJlbWVudF9kYXRhJHZQMQpgYGAKCmBgYHtyfQojIENvbnZlcnQgdHJlYXRkYXRlIHRvIHByb3BlciBEYXRlIGZvcm1hdAoKZW9kX21lYXN1cmVtZW50X2RhdGEgPC0gZmlsdGVyKGVvZF9tZWFzdXJlbWVudF9kYXRhLCBwZXJpb2Q9PSJFWFBUIikKCmVvZF9tZWFzdXJlbWVudF9kYXRhIDwtIGVvZF9tZWFzdXJlbWVudF9kYXRhICU+JQogIG11dGF0ZSh0cmVhdGRhdGUgPSBhcy5EYXRlKHRyZWF0ZGF0ZSwgZm9ybWF0ID0gIiVkLSViIikpCgojIENhbGN1bGF0ZSBuX2RheXMKZW9kX21lYXN1cmVtZW50X2RhdGEgPC0gZW9kX21lYXN1cmVtZW50X2RhdGEgJT4lCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lCiAgbXV0YXRlKG5fZGF5cyA9IGFzLm51bWVyaWModHJlYXRkYXRlIC0gbWluKHRyZWF0ZGF0ZSkpKSAlPiUKICBtdXRhdGUodHJlYXRfZGF5ID0gY2FzZV93aGVuKAogICAgKHRyZWF0ZW1lbnQgJWluJSBjKCJUOCIsICJDT04iKSAmIG5fZGF5cyA9PSA4KSB+ICJsYXN0IiwKICAgICh0cmVhdGVtZW50ICVpbiUgYygiVDgiLCAiQ09OIikgJiBuX2RheXMgPT0gMCkgfiAiZmlyc3QiLAogICAgKHRyZWF0ZW1lbnQgPT0gIlQxIiAmIG5fZGF5cyA9PSAxKSB+ICJsYXN0IiwKICAgICh0cmVhdGVtZW50ID09ICJUMSIgJiBuX2RheXMgPT0gMCkgfiAiZmlyc3QiLAogICAgVFJVRSB+IE5BX2NoYXJhY3Rlcl8gIyBBbGwgb3RoZXIgcm93cyBhcmUgTkEKICApKSAlPiUKICB1bmdyb3VwKCkKCiMgVmlldyB0aGUgcmVzdWx0CnByaW50KGVvZF9tZWFzdXJlbWVudF9kYXRhKQpgYGAKCmBgYHtyfQpmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhIDwtIGVvZF9tZWFzdXJlbWVudF9kYXRhICU+JQogIGZpbHRlcighaXMubmEodHJlYXRfZGF5KSkKZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSR0cmVhdF9kYXk8LWFzLmZhY3RvcihmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhJHRyZWF0X2RheSkKYGBgCgoKCiMjIER1cmF0aW9uCkxldCdzIGNoZWNrIG92ZXJhbGwgZHVyYXRpb24gZmlyc3QuICBUaGlzIGhhcyBiZWVuIHVwZGF0ZWQgdG8gY2FsY3VsYXRlIGR1cmF0aW9uIHRoZSB3YXkgdGhhdCBNYXUgZG9lcywgc28gdGhlIHJlc3VsdHMgc2hvdWxkIGJlIGlkZW50aWNhbC4KCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gImR1cmF0aW9uIiwKICB5X2F4aXNfbGFiZWwgPSAiRU9EIGR1cmF0aW9uIChtc2VjKSIKKQoKIyBEaXNwbGF5IHRoZSBwbG90CnByaW50KHJlc3VsdHMkcGxvdCkKcmVzdWx0cyRhbm92YQpyZXN1bHRzJHBvc3Rob2MKYGBgCiMjIFAxIER1cmF0aW9uIGFuZCBQMiBEdXJhdGlvbgpQMSBkdXJhdGlvbiBkb2VzIGluY3JlYXNlIGluIFQ4IGRheSwgYnV0IG5vdCBieSBhIGh1Z2UgbWFyZ2luLiAgUDIgZHVyYXRpb24sIGhvd2V2ZXIgaW5jcmVhc2VzIHByZXR0eSBzdWJzdGFudGlhbGx5LiAgSW50ZXJlc3RpbmcuLi4KYGBge3J9CnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAicDFfZHVyYXRpb24iLAogIHlfYXhpc19sYWJlbCA9ICJQMSBkdXJhdGlvbiAobXNlYykiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCmBgYAoKCgpgYGB7cn0KCnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAicDJfZHVyYXRpb24iLAogIHlfYXhpc19sYWJlbCA9ICJQMiBkdXJhdGlvbiAobXNlYykiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCgpgYGAKCiMjIFJhdGlvIG9mIHZQMiB0byB2UDEKCkEgbGFyZ2VyIG5lZ2F0aXZlIHZhbHVlIG1lYW5zIHRoYXQgUDIgaXMgImJpZ2dlciIgdGhhbiBQMS4gIFdlIGNhbiBzZWUgdGhhdCBWUDIgaXMgYWx3YXlzIGxhcmdlciBvbiB0aGUgZmlyc3QgZGF5LCBidXQgYmVjb21lcyBtb3JlIHByb3BvcnRpb25hbCBhZnRlciA4IGRheXMgb2YgVCB0cmVhdG1lbnQuICBEb2VzIHRoaXMgc3VnZ2VzdCBsZXNzIE5hKyBleHByZXNzaW9uPwoKYGBge3J9CnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAidlAyLnZQMS5yYXRpbyIsCiAgeV9heGlzX2xhYmVsID0gInZQMi92UDEgcmF0aW8iCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCmBgYAoKCgpgYGB7cn0KcmVzdWx0cyA8LSBjcmVhdGVfc2lnbmlmaWNhbmNlX3Bsb3QoCiAgZGF0YSA9IGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEsCiAgeV92YXJpYWJsZSA9ICJ2UDIiLAogIHlfYXhpc19sYWJlbCA9ICJ2UDIiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCmBgYAoKYGBge3J9CnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAidlAxIiwKICB5X2F4aXNfbGFiZWwgPSAidlAxIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwpgYGAKCgojIyBQMS1QMiBEZWxheQpTaW5jZSBQMSBpcyBkZWZpbmVkIGFzIFQ9MCwgdGhlbiB0UDIgaXMgdGhlIHJlbGF0aXZlIHRpbWluZyBvZiBQMi4KV2UgY2FuIHNlZSB0aGF0IGl0IHRha2VzIGxvbmdlciB0byByZWFjaCBQMiBhZnRlciA4IGRheXMgb2YgVCB0cmVhdG1lbnQsIHN1Z2dlc3RpbmcgdGhlIGFjdGlvbiBwb3RlbnRpYWxzIGFyZSBkZWxheWVkIHJlbGF0aXZlIHRvIGVhY2ggb3RoZXIgKGNhcGFjaXRhbmNlPykKCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gInRQMiIsCiAgeV9heGlzX2xhYmVsID0gIlAxLVAyIERlbGF5IChtc2VjKSIKKQoKIyBEaXNwbGF5IHRoZSBwbG90CnByaW50KHJlc3VsdHMkcGxvdCkKcmVzdWx0cyRhbm92YQpyZXN1bHRzJHBvc3Rob2MKYGBgCiMjIFAyIERlY2F5IFRpbWUgQ29uc3RhbnQKIEEgbGFyZ2VyIM+EIGluZGljYXRlcyB0aGF0IHRoZSBkZWNheSBoYXBwZW5zIG1vcmUgcmFwaWRseS4gVGhpcyBtZWFucyBQMidzIGFtcGxpdHVkZSBkaW1pbmlzaGVzIG92ZXIgYSBsYXJnZXIgdGltZSBhZnRlciB0ZXN0YXN0ZXJvbmUgdHJlYXRtZW50LiAgVGhpcyBzdWdnZXN0cyBpbmNyZWFzZWQgcG90YXNzaXVtIGNoYW5uZWwgZXhwcmVzc2lvbiwgSSB0aGluay4KCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gImRlY2F5X3RhdSIsCiAgeV9heGlzX2xhYmVsID0gIs+EIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwpgYGAKIyMgU2xvcGUgb2YgUDEKClRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaGVyZS4KCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gInNTMSIsCiAgeV9heGlzX2xhYmVsID0gIlNsb3BlIG9mIFAxIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwoKYGBgCiMjIFAwCgpQMCBkb2VzIGluIGZhY3QgZ2V0IGxhcmdlciB3aXRoIHRlc3Rhc3Rlcm9uZSB0cmVhdG1lbnQgYXMgd2VsbCwgdGhvdWdoIGludGVyZXN0aW5nbHksIHRoZSBwZWFrIHZvbHRhZ2Ugc3RheXMgdGhlIHNhbWUsIHN1Z2dlc3RpbmcgdGhhdCB0aGlzIGNoYW5nZSBpcyBiZWNhdXNlIHRoZSBwZWFrIGlzIGJyb2FkZXIgKGxhc3RzIGxvbmdlcikuICBOb3Qgc3VyZSB3aGF0IHdvdWxkIGFmZmVjdCB0aGlzLCBvdGhlciB0aGFuIHRoZSBlbGVjdHJvY3l0ZSBnZXR0aW5nIHRoaWNrZXI/ICBXZSBkb24ndCBrbm93IG11Y2ggYWJvdXQgdGhlIGlvbiBjaGFubmVscyBwcmVzZW50IG9uIHRoZSBzdGFsa3MsIHNvIHRoaXMgaXMgYW4gaW50ZXJlc3RpbmcgcG9pbnQgdG8gY29uc2lkZXIgaW4gYSBmdXR1cmUgc3R1ZHkuCgpgYGB7cn0KcmVzdWx0cyA8LSBjcmVhdGVfc2lnbmlmaWNhbmNlX3Bsb3QoCiAgZGF0YSA9IGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEsCiAgeV92YXJpYWJsZSA9ICJhUDAiLAogIHlfYXhpc19sYWJlbCA9ICJBcmVhIFAwIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwpgYGAKCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gInZQMCIsCiAgeV9heGlzX2xhYmVsID0gIlZvbHRhZ2Ugb2YgUDAiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCgpgYGAKIyMgU3VtbWFyeSBUYWJsZSBvZiBBbGwgQ29tcGFyaXNpb25zCgpUaGlzIGNvZGUgZ2VuZXJhdGVzIGEgc3VtbWFyeSB0YWJsZSBhbmQgb3V0cHV0cyB0byB3b3JkIGZvciBlZGl0aW5nIGFuZCBpbmNsdXNpb24gaW4gdGhlIG1hbnVzY3JpcHQuCgpgYGB7cn0Kc3RhdGlzdGljcyA8LSBjKCJkdXJhdGlvbiIsICJwMV9kdXJhdGlvbiIsICJwMl9kdXJhdGlvbiIsICJ2UDIudlAxLnJhdGlvIiwgInRQMiIsICJkZWNheV90YXUiLCJhUDAiLCJ2UDAiLCJzUzEiLCJ2UDEiLCJ2UDIiKQoKIyBGaWx0ZXIsIHN1bW1hcml6ZSwgYW5kIGZvcm1hdApzdW1tYXJ5X3RhYmxlIDwtIGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEgJT4lCiAgZ3JvdXBfYnkodHJlYXRfZGF5LCB0cmVhdGVtZW50KSAlPiUgICAgICAgICAgICAjIEdyb3VwIGJ5IG5fZGF5cyBhbmQgdHJlYXRtZW50CiAgc3VtbWFyaXNlKGFjcm9zcyhhbGxfb2Yoc3RhdGlzdGljcyksCiAgICAgICAgICAgICAgICAgICB+IHNwcmludGYoIiUuMmYgwrEgJS4yZiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oLngsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkKC54LCBuYS5ybSA9IFRSVUUpKSwKICAgICAgICAgICAgICAgICAgIC5uYW1lcyA9ICJ7Y29sfSIpKSAlPiUgICAgICMgQ29tYmluZSBtZWFuIGFuZCBzZCBpbnRvIGEgc2luZ2xlIGNvbHVtbgogIHVuZ3JvdXAoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZW1vdmUgZ3JvdXBpbmcKCgpjb2xuYW1lcyhzdW1tYXJ5X3RhYmxlKTwtYygiVHJlYXRtZW50IERheSIsIlRyZWF0bWVudCIsIkR1cmF0aW9uIiwiUDEgRHVyYXRpb24iLCJQMiBEdXJhdGlvbiIsInZQMi92UDEiLCJ0UDIiLCLPhCIsImFQMCIsInZQMCIsInNTMSIsInZQMSIsInZQMiIpCgojIENyZWF0ZSB0aGUgZmxleHRhYmxlCmZsZXh0YWJsZV90YWJsZSA8LSBmbGV4dGFibGUoc3VtbWFyeV90YWJsZSkgJT4lCiAgYmcocGFydCA9ICJoZWFkZXIiLCBiZyA9ICIjRDNEM0QzIikgJT4lICAjIFNldCBoZWFkZXIgYmFja2dyb3VuZCBjb2xvcgogIGJvbGQocGFydCA9ICJoZWFkZXIiKSAlPiUgICAgICAgICAgICAgICAjIEJvbGQgdGhlIGhlYWRlciByb3cKICBmb250c2l6ZShzaXplID0gMTAsIHBhcnQgPSAiYWxsIikgJT4lICAgIyBTZXQgZm9udCBzaXplIGZvciB0aGUgZW50aXJlIHRhYmxlCiAgYXV0b2ZpdCgpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQWRqdXN0IGNvbHVtbiB3aWR0aHMKICBzZXRfdGFibGVfcHJvcGVydGllcyhsYXlvdXQgPSAiYXV0b2ZpdCIpICU+JSAgICAgICMgRml0IHRhYmxlIHRvIGxheW91dAogIGxpbmVfc3BhY2luZyhpID0gTlVMTCwgc3BhY2UgPSAxLjIpICAgICAjIEFkZCBsaW5lIHNwYWNpbmcgZm9yIGJldHRlciByZWFkYWJpbGl0eQoKIyBEZWZpbmUgbGFuZHNjYXBlIHNlY3Rpb24gcHJvcGVydGllcwpsYW5kc2NhcGVfc2VjdGlvbiA8LSBibG9ja19zZWN0aW9uKAogIHByb3Bfc2VjdGlvbigKICAgIHBhZ2Vfc2l6ZSA9IHBhZ2Vfc2l6ZShvcmllbnQgPSAibGFuZHNjYXBlIikgIyBTZXQgdGhlIHBhZ2Ugb3JpZW50YXRpb24gdG8gbGFuZHNjYXBlCiAgKQopCgojIENyZWF0ZSB0aGUgV29yZCBkb2N1bWVudApkb2MgPC0gcmVhZF9kb2N4KCkgJT4lCiAgYm9keV9hZGRfZmxleHRhYmxlKGZsZXh0YWJsZV90YWJsZSkgJT4lICMgQWRkIHRoZSBmbGV4dGFibGUKICBib2R5X2FkZChsYW5kc2NhcGVfc2VjdGlvbikgICAgICAjIEFwcGx5IGxhbmRzY2FwZSBzZWN0aW9uIHByb3BlcnRpZXMKCgojIEV4cG9ydCB0aGUgV29yZCBkb2N1bWVudApwcmludChkb2MsIHRhcmdldCA9IGZpbGUucGF0aChyb290LCJvdXRwdXRfZGF0YS9lb2Rfc3VtbWFyeV9ub3JtLmRvY3giKSkKCmZsZXh0YWJsZV90YWJsZQpgYGAKCgpgYGB7cn0KbGlicmFyeShtdWx0Y29tcFZpZXcpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZHBseXIpCgojIERlZmluZSB0aGUgbGlzdCBvZiB2YXJpYWJsZXMgZm9yIHdoaWNoIHlvdSB3YW50IHRvIGFkZCBzaWduaWZpY2FuY2UgbGV0dGVycy4Kc3RhdGlzdGljcyA8LSBjKCJkdXJhdGlvbiIsICJwMV9kdXJhdGlvbiIsICJwMl9kdXJhdGlvbiIsICJ2UDIudlAxLnJhdGlvIiwgCiAgICAgICAgICAgICAgICAidFAyIiwgImRlY2F5X3RhdSIsICJhUDAiLCAidlAwIiwgInNTMSIsICJ2UDEiLCAidlAyIikKCmdldF9sZXR0ZXJzX2J5X2RheSA8LSBmdW5jdGlvbihkZiwgZ3JvdXBfaW5mbywgdmFyKSB7CiAgIyBSdW4gVHVrZXkncyB0ZXN0IGZvciB0aGUgZ2l2ZW4gdmFyaWFibGUKICB0dWtleV9yZXMgPC0gdHVrZXlfaHNkKGRmLCBhcy5mb3JtdWxhKHBhc3RlKHZhciwgIn4gdHJlYXRlbWVudCIpKSkKICAKICAjIENyZWF0ZSBhIG1hdHJpeCBvZiBwLXZhbHVlcyBiZXR3ZWVuIHRyZWF0bWVudCBncm91cHMKICBncm91cHMgPC0gc29ydCh1bmlxdWUoZGYkdHJlYXRlbWVudCkpCiAgcG1hdCA8LSBtYXRyaXgoMSwgbnJvdyA9IGxlbmd0aChncm91cHMpLCBuY29sID0gbGVuZ3RoKGdyb3VwcyksCiAgICAgICAgICAgICAgICAgZGltbmFtZXMgPSBsaXN0KGdyb3VwcywgZ3JvdXBzKSkKICAKICBpZihucm93KHR1a2V5X3JlcykgPiAwKSB7CiAgICBmb3IoaSBpbiBzZXFfbGVuKG5yb3codHVrZXlfcmVzKSkpIHsKICAgICAgZ3JwMSA8LSB0dWtleV9yZXMkZ3JvdXAxW2ldCiAgICAgIGdycDIgPC0gdHVrZXlfcmVzJGdyb3VwMltpXQogICAgICBwX3ZhbCA8LSB0dWtleV9yZXMkcC5hZGpbaV0KICAgICAgcG1hdFtncnAxLCBncnAyXSA8LSBwX3ZhbAogICAgICBwbWF0W2dycDIsIGdycDFdIDwtIHBfdmFsCiAgICB9CiAgfQogIAogICMgQ29tcHV0ZSBncm91cGluZyBsZXR0ZXJzCiAgbGV0dGVyc19vdXQgPC0gbXVsdGNvbXBMZXR0ZXJzKHBtYXQsIHRocmVzaG9sZCA9IDAuMDUpJExldHRlcnMKICAKICAjIFJldHVybiBvbmx5IHRoZSB0cmVhdG1lbnQgYW5kIGxldHRlciBjb2x1bW5zLgogICMgVGhlIGdyb3VwaW5nIHZhcmlhYmxlICh0cmVhdF9kYXkpIGlzIGFkZGVkIGF1dG9tYXRpY2FsbHkuCiAgZGF0YS5mcmFtZSh0cmVhdGVtZW50ID0gbmFtZXMobGV0dGVyc19vdXQpLCAKICAgICAgICAgICAgIGxldHRlciA9IGxldHRlcnNfb3V0LCAKICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKfQoKCgpsZXR0ZXJzX2xpc3QgPC0gbGFwcGx5KHN0YXRpc3RpY3MsIGZ1bmN0aW9uKHZhcikgewogIGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEgJT4lCiAgICBncm91cF9ieSh0cmVhdF9kYXkpICU+JQogICAgZ3JvdXBfbW9kaWZ5KH4gZ2V0X2xldHRlcnNfYnlfZGF5KC54LCAueSwgdmFyKSkgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBtdXRhdGUodmFyaWFibGUgPSB2YXIpCn0pCmFsbF9sZXR0ZXJzIDwtIGJpbmRfcm93cyhsZXR0ZXJzX2xpc3QpCgoKCiMgTm93LCBjcmVhdGUgeW91ciBzdW1tYXJ5IHRhYmxlIGFzIGJlZm9yZS4KIyAoV2UgYXNzdW1lIHRoZSBzdW1tYXJ5X3RhYmxlIHdhcyBjb21wdXRlZCBhcyBpbiB5b3VyIHByZXZpb3VzIGNodW5rLikKc3VtbWFyeV90YWJsZSA8LSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhICU+JQogIGdyb3VwX2J5KHRyZWF0X2RheSwgdHJlYXRlbWVudCkgJT4lICAjIEdyb3VwIGJ5IGRheSBhbmQgdHJlYXRtZW50CiAgc3VtbWFyaXNlKGFjcm9zcyhhbGxfb2Yoc3RhdGlzdGljcyksCiAgICAgICAgICAgICAgICAgICB+IHNwcmludGYoIiUuMmYgwrEgJS4yZiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oLngsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkKC54LCBuYS5ybSA9IFRSVUUpKSksCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICAjIENvbWJpbmUgbWVhbiBhbmQgc2QgaW50byBhIHNpbmdsZSBjb2x1bW4KCiMgRm9yIG5pY2VyIGNvbHVtbiBuYW1lcywgcmVuYW1lICh5b3UgY2FuIGFkanVzdCB0aGlzIG1hcHBpbmcgYXMgbmVlZGVkKS4KY29sbmFtZXMoc3VtbWFyeV90YWJsZSkgPC0gYygiVHJlYXRtZW50IERheSIsIlRyZWF0bWVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkR1cmF0aW9uIiwiUDEgRHVyYXRpb24iLCJQMiBEdXJhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZQMi92UDEiLCJ0UDIiLCLPhCIsImFQMCIsInZQMCIsInNTMSIsInZQMSIsInZQMiIpCgojIFNpbmNlIG91ciBsZXR0ZXJzIGFyZSBrZXllZCBieSB0aGUgb3JpZ2luYWwgdmFyaWFibGUgbmFtZXMgKGUuZy4sICJkdXJhdGlvbiIpIAojIHdlIHNldCB1cCBhIG1hcHBpbmcgdG8gbWF0Y2ggdGhlIHN1bW1hcnlfdGFibGUgY29sdW1ucy4KbWFwcGluZ19kZiA8LSB0aWJibGUoCiAgVmFyaWFibGUgPSBjKCJEdXJhdGlvbiIsICJQMSBEdXJhdGlvbiIsICJQMiBEdXJhdGlvbiIsICJ2UDIvdlAxIiwgCiAgICAgICAgICAgICAgICJ0UDIiLCAiz4QiLCAiYVAwIiwgInZQMCIsICJzUzEiLCAidlAxIiwgInZQMiIpLAogIHZhciA9IHN0YXRpc3RpY3MKKQoKIyBSZXNoYXBlIHRoZSBzdW1tYXJ5X3RhYmxlIHRvIGxvbmcgZm9ybWF0IHRvIG1lcmdlIHRoZSBsZXR0ZXJzLgpzdW1tYXJ5X2xvbmcgPC0gc3VtbWFyeV90YWJsZSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1jKGBUcmVhdG1lbnQgRGF5YCwgVHJlYXRtZW50KSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiVmFyaWFibGUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiU3VtbWFyeSIpICU+JQogIGxlZnRfam9pbihtYXBwaW5nX2RmLCBieSA9ICJWYXJpYWJsZSIpCgojIE1lcmdlIHdpdGggdGhlIGxldHRlcnMgKGpvaW4gYnkgdHJlYXRfZGF5L1RyZWF0bWVudCBhbmQgdGhlIHZhcmlhYmxlIGtleSkuCiMgTm90ZTogSW4gc3VtbWFyeV90YWJsZSwgIlRyZWF0bWVudCBEYXkiIGNvcnJlc3BvbmRzIHRvICJ0cmVhdF9kYXkiIGluIGFsbF9sZXR0ZXJzLgpzdW1tYXJ5X2xvbmcgPC0gc3VtbWFyeV9sb25nICU+JQogIGxlZnRfam9pbihhbGxfbGV0dGVycywgYnkgPSBjKCJ2YXIiID0gInZhcmlhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJlYXRtZW50IERheSIgPSAidHJlYXRfZGF5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJlYXRtZW50IiA9ICJ0cmVhdGVtZW50IikpCgojIEFwcGVuZCB0aGUgc2lnbmlmaWNhbmNlIGxldHRlciAoaWYgYXZhaWxhYmxlKSB0byB0aGUgc3VtbWFyeSBzdHJpbmcuCnN1bW1hcnlfbG9uZyA8LSBzdW1tYXJ5X2xvbmcgJT4lCiAgbXV0YXRlKFN1bW1hcnkgPSBpZmVsc2UoaXMubmEobGV0dGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBTdW1tYXJ5LAogICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMChTdW1tYXJ5LCAiICgiLCBsZXR0ZXIsICIpIikpKQoKIyAoT3B0aW9uYWwpIFBpdm90IGJhY2sgdG8gd2lkZSBmb3JtYXQuCnN1bW1hcnlfd2lkZSA8LSBzdW1tYXJ5X2xvbmcgJT4lCiAgc2VsZWN0KC12YXIsIC1sZXR0ZXIpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBWYXJpYWJsZSwgdmFsdWVzX2Zyb20gPSBTdW1tYXJ5KQoKIyBDcmVhdGUgYSBmbGV4dGFibGUgZnJvbSB0aGUgdXBkYXRlZCBzdW1tYXJ5X3dpZGUgdGFibGUuCmZsZXh0YWJsZV90YWJsZV9zaWcgPC0gZmxleHRhYmxlKHN1bW1hcnlfd2lkZSkgJT4lCiAgYmcocGFydCA9ICJoZWFkZXIiLCBiZyA9ICIjRDNEM0QzIikgJT4lICAjIEhlYWRlciBiYWNrZ3JvdW5kIGNvbG9yCiAgYm9sZChwYXJ0ID0gImhlYWRlciIpICU+JSAgICAgICAgICAgICAgICMgQm9sZCBoZWFkZXIgcm93CiAgZm9udHNpemUoc2l6ZSA9IDEwLCBwYXJ0ID0gImFsbCIpICU+JSAgICMgRm9udCBzaXplIGZvciBlbnRpcmUgdGFibGUKICBhdXRvZml0KCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBBZGp1c3QgY29sdW1uIHdpZHRocwogIHNldF90YWJsZV9wcm9wZXJ0aWVzKGxheW91dCA9ICJhdXRvZml0IikgJT4lICAgICAgIyBGaXQgdGFibGUgdG8gbGF5b3V0CiAgbGluZV9zcGFjaW5nKGkgPSBOVUxMLCBzcGFjZSA9IDEuMikgICAgICAgIyBCZXR0ZXIgcmVhZGFiaWxpdHkKCiMgRGVmaW5lIGxhbmRzY2FwZSBzZWN0aW9uIHByb3BlcnRpZXMgZm9yIFdvcmQgZXhwb3J0CmxhbmRzY2FwZV9zZWN0aW9uIDwtIGJsb2NrX3NlY3Rpb24oCiAgcHJvcF9zZWN0aW9uKAogICAgcGFnZV9zaXplID0gcGFnZV9zaXplKG9yaWVudCA9ICJsYW5kc2NhcGUiKSAjIExhbmRzY2FwZSBvcmllbnRhdGlvbgogICkKKQoKIyBDcmVhdGUgdGhlIFdvcmQgZG9jdW1lbnQgd2l0aCB0aGUgdXBkYXRlZCBmbGV4dGFibGUuCmRvYyA8LSByZWFkX2RvY3goKSAlPiUKICBib2R5X2FkZF9mbGV4dGFibGUoZmxleHRhYmxlX3RhYmxlX3NpZykgJT4lICAjIEFkZCBmbGV4dGFibGUKICBib2R5X2FkZChsYW5kc2NhcGVfc2VjdGlvbikgICAgICAgICAgICAgICAgICAjIEFwcGx5IGxhbmRzY2FwZSBsYXlvdXQKCiMgRXhwb3J0IHRoZSBXb3JkIGRvY3VtZW50LgpwcmludChkb2MsIHRhcmdldCA9IGZpbGUucGF0aChyb290LCJvdXRwdXRfZGF0YS9lb2Rfc3VtbWFyeV9ub3JtX3dpdGhfc2lnLmRvY3giKSkKCiMgRGlzcGxheSB0aGUgdXBkYXRlZCBmbGV4dGFibGUgaW4gdGhlIFIgTWFya2Rvd24gb3V0cHV0LgpmbGV4dGFibGVfdGFibGVfc2lnCmBgYA==